package com.nercel.dsj.gksales.util;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
public class SignUtil {

    public static String sign(Map<String, Object> params, String key){
        List<String> keys = (new ArrayList<>(params.keySet()));
        Collections.sort(keys);
        List<String> items = new ArrayList<>();
        keys.forEach(item->{
            if(!item.equalsIgnoreCase("sign")){
                items.add(item + "=" + (params.get(item) == null ? "" : params.get(item).toString()));
            }
        });
        String paramsStr = String.join("&", items);
        paramsStr = paramsStr + "&key=" + key;
        System.out.println(paramsStr);
        return Md5Util.getMD5String(paramsStr).toUpperCase();
    }

    @SuppressWarnings("unchecked")
	public static boolean verifySign(HttpServletRequest request, String key) {
        try {
            String bodyStr = IOUtils.toString(request.getInputStream(), "utf-8");
            Map<String,Object> params = JSONUtil.jsonString2Map(bodyStr);
            String sign = (String)params.get("sign");
            if(sign != null && sign.equals(SignUtil.sign(params, key))){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * @param params 所有的请求参数都会在这里进行排序加密
     * @return 验证签名结果
     */
    public static boolean verifySign(SortedMap<String, String> params) {

        String urlSign = params.get("sign");
        log.info("Url Sign : {}", urlSign);
        if (params == null || StringUtils.isEmpty(urlSign)) {
            return false;
        }
        //把参数加密
        String paramsSign = getParamsSign(params);
        log.info("Param Sign : {}", paramsSign);
        return !StringUtils.isEmpty(paramsSign) && urlSign.equals(paramsSign);
    }

    /**
     * @param params 所有的请求参数都会在这里进行排序加密
     * @return 得到签名
     */
    public static String getParamsSign(SortedMap<String, String> params) {
        //要先去掉 Url 里的 Sign
        params.remove("sign");
        String paramsJsonStr = JSONObject.toJSONString(params);
        return DigestUtils.md5DigestAsHex(paramsJsonStr.getBytes()).toUpperCase();
    }
}